# -*- coding: utf-8 -*-
from formencode.validators import FancyValidator, Invalid

__all__ = ["Estado"]

class Estado(FancyValidator):
    u"""
    Esta classe é responsável por validar se um Estado informado realmente
    existe.

    A utilização dá-se como para outros validadores do FormEncode, o que permite
    que este validador seja usado em conjunto com outros não providos aqui ou
    então em regras mais complexas de validação.

    Quando enviando um valor para o validador Python ele compara se o valor é
    uma abreviatura ou se é um nome de Estado.  Em caso de abreviatura, o
    validador faz a comparação com a lista de abreviaturas válidas e retorna a
    abreviatura caso esta seja válida.  Em caso de um nome por extenso, o
    validador retorna a abreviatura correspondente ao Estado informado.

    O retorno do código Python para o usuário dá-se de acordo com os parâmetros
    only_abbrev e only_name: caso only_abbrev seja definido como verdadeiro,
    retorna-se apenas a abreviatura, caso este seja falso, verifica-se o valor
    de only_name e caso verdadeiro, retorna-se apenas o nome do Estado.  Caso
    ambos sejam falsos, retorna-se um dicionário contendo a abreviatura e o
    nome do Estado.


    Parâmetros:

    value       -> valor que sofrerá a ação
    messages    -> dicionário contendo as mensagens de erro
    only_abbrev -> retorna apenas a abreviatura do Estado se verdadeiro
    only_name   -> retorna apenas o nome do Estado se verdadeiro

    Valores padrão:

    only_abbrev: False
    only_name:   False
    """

    only_abbrev = False
    only_name = False

    messages = {
        'empty': 'Por favor escolha um Estado',
        'invalid': 'Estado invalido',
        'abbrev': 'Abreviatura incorreta',
        }

    # Fonte: http://www.ibge.gov.br/estadosat/
    estados_validos = {
        'AC': u'Acre',
        'AL': u'Alagoas',
        'AM': u'Amazonas',
        'AP': u'Amapá',
        'BA': u'Bahia',
        'CE': u'Ceará',
        'DF': u'Distrito Federal',
        'ES': u'Espírito Santo',
        'GO': u'Goiás',
        'MA': u'Maranhão',
        'MG': u'Minas Gerais',
        'MT': u'Mato Grosso',
        'MS': u'Mato Grosso do Sul',
        'PA': u'Pará',
        'PB': u'Paraíba',
        'PE': u'Pernambuco',
        'PI': u'Piauí',
        'PR': u'Paraná',
        'RJ': u'Rio de Janeiro',
        'RN': u'Rio Grande do Norte',
        'RO': u'Rondônia',
        'RR': u'Roraima',
        'RS': u'Rio Grande do Sul',
        'SC': u'Santa Catarina',
        'SE': u'Sergipe',
        'SP': u'São Paulo',
        'TO': u'Tocantins',
        }


    def _to_python(self, value, state):
        self.assert_string(value, state)

        if len(value) == 2:
            if value not in self.estados_validos.keys():
                raise Invalid(self.message('invalid', state), value, state)
            return value

        if value not in self.estados_validos.values():
            raise Invalid(self.message('invalid', state), value, state)

        for item in self.estados_validos:
            if self.estados_validos[item] == value:
                return item


    def _from_python(self, value, state):
        if len(value) != 2:
            raise Invalid(self.message('abbrev', state), value, state)

        if self.only_abbrev:
            if value in self.estados_validos.keys():
                return value
            else:
                raise Invalid(self.message('invalid', state), value, state)

        if self.only_name:
            try:
                return self.estados_validos[value]
            except KeyError:
                raise Invalid(self.message('invalid', state), value, state)

        try:
            return {value:self.estados_validos[value]}
        except KeyError:
            raise Invalid(self.message('invalid', state), value, state)
